package com.koala.utils;

/**
 * @author yantingrui
 * @date 2021/7/30   15:58
 */

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author koala
 * @Description: orika 的工具类
 * @date 2021/7/12   17:25
 */
public class OrikaUtil {

    private static MapperFacade mapper = null;


    static {
        DefaultMapperFactory build = new DefaultMapperFactory.Builder().build();
        mapper = build.getMapperFacade();
    }


    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 简单的赋值拷贝
     */
    public static <S, D> D map(S source, Class<D> destinationClass) {
        return mapper.map(source, destinationClass);
    }


    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 极致性能拷贝对象
     */
    public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
        return mapper.map(source, sourceType, destinationType);
    }

    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 复制出对象列表到ArrayList
     */
    public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
        return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
    }

    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 极致复制对象到ArrayList
     */
    public static <S, D> List<S> mapList(Iterable<D> sourceList, Type<S> sourceType, Type<D> destinationType) {
        return mapper.mapAsList(sourceList, destinationType, sourceType);
    }

    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 简单复制出新对象列表到数组
     */
    public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
        return mapper.mapAsArray(destination, source, destinationClass);
    }

    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 致性能的复制出新类型对象到数组
     */
    public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
        return mapper.mapAsArray(destination, source, sourceType, destinationType);
    }

    /**
     * @param ${tags}
     * @return ${return_type}
     * @Description: 预先获取orika转换所需要的Type，避免每次转换.
     */
    public static <E> Type<E> getType(final Class<E> rawType) {
        return TypeFactory.valueOf(rawType);
    }


    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }


}

